package com.yitao.cms.utils;


import com.skipper.base.exception.ServerErrorException;
import com.skipper.base.json.JSON;
import com.skipper.base.json.JSONObject;
import com.skipper.base.utils.HttpUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.SocketConfig;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StreamUtils;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;

public class HttpUtil {
	
    private static Logger logger = LoggerFactory.getLogger(HttpUtil.class);
    
	 public static final HttpClient DEFAULT_HTTP_CLIENT = HttpClientBuilder.create()
	            //设置默认时间
	            .setUserAgent("BAINUO.COM")
	            .setDefaultRequestConfig(RequestConfig.custom()
	                    .setConnectTimeout(5000)         //连接超时时间(ms)
	                    .setSocketTimeout(5000)          //读超时时间（等待数据超时时间）(ms)
	                    .setConnectionRequestTimeout(500)    //从池中获取连接超时时间(ms)
	                    .build())
	            .setConnectionManager(new PoolingHttpClientConnectionManager() {{
	                setMaxTotal(200);//最大连接数
	                setDefaultMaxPerRoute(10);//默认的每个路由的最大连接数
	                setDefaultSocketConfig(SocketConfig.custom()
	                        .setSoReuseAddress(true) //是否可以在一个进程关闭Socket后，即使它还没有释放端口，其它进程还可以立即重用端口
	                        .setSoTimeout(5000)       //接收数据的等待超时时间，单位ms
	                        .setSoKeepAlive(true)    //开启监视TCP连接是否有效
	                        .build()
	                );
	            }})

	            .build();
	/**
	 * 基于HttpClient 4.3的通用POST方法
	 *
	 * @param url
	 *            提交的URL
	 * @param paramsMap
	 *            提交<参数，值>Map
	 * @return 提交响应
	 */
	public static String post(String url, Map<String, String> paramsMap) {
		CloseableHttpClient client = HttpClients.createDefault();
		String responseText = "";
		CloseableHttpResponse response = null;
		try {
			HttpPost method = new HttpPost(url);
			if (paramsMap != null) {
				List<NameValuePair> paramList = new ArrayList<NameValuePair>();
				for (Map.Entry<String, String> param : paramsMap.entrySet()) {
					NameValuePair pair = new BasicNameValuePair(param.getKey(), param.getValue());
					paramList.add(pair);
				}
				method.setEntity(new UrlEncodedFormEntity(paramList, "UTF-8"));
			}
			RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).setConnectionRequestTimeout(5000).build();
			method.setConfig(requestConfig);
			response = client.execute(method);
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				responseText = EntityUtils.toString(entity);
			}
		} catch (Exception e) {
			logger.error("连接超时", e.getMessage());
			return responseText;
		} finally {
			try {
				response.close();
			} catch (Exception e) {
				logger.error("关闭response异常" + e.getMessage());
				return responseText;
			}
		}
		return responseText;
	}

	public static String get(String url) {
		CloseableHttpClient client = HttpClients.createDefault();
		String responseText = "";
		CloseableHttpResponse response = null;
		try {
			HttpGet method = new HttpGet(url);
			response = client.execute(method);
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				responseText = EntityUtils.toString(entity);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				response.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return responseText;
	}
	
	/**
     * POST 上传文件
     *
     * @param url
     * @param file
     * @param headers
     * @return
     */
    public static String postFile(String url, File file, Map<String, String> headers, Map<String, String> form) {
        try {
            HttpPost request = new HttpPost(url);
            if (null == file || !file.exists() || !file.isFile() || !file.canRead()) {
                Assert.isTrue(false, "上传文件无效");
            }
            //设置请求头
            if (!CollectionUtils.isEmpty(headers)) {
                headers.entrySet().forEach(entry -> {
                    request.setHeader(entry.getKey(), entry.getValue());
                });
            }

            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            //添加form表单
            if (null != form && form.keySet().size() > 0) {
                for (String key : form.keySet()) {
                    builder.addTextBody(key, form.get(key), ContentType.create("text/plain", Consts.UTF_8));
                }
            }
            //添加文件
            builder.addBinaryBody("file", file, ContentType.APPLICATION_OCTET_STREAM, file.getName());

            //设置请求体
            request.setEntity(builder.build());

            return DEFAULT_HTTP_CLIENT.execute(request, response -> {
                //HTTP响应信息默认处理方法
                try {
                    String responseBody = StreamUtils.copyToString(response.getEntity().getContent(), StandardCharsets.UTF_8);
                    if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                        logger.info("http请求结果异常：{} {}", response.getStatusLine(), responseBody);
                        throw new HttpUtils.HttpException(request, response, responseBody);
                    }
                    return responseBody;
                } catch (IOException ex) {
                    logger.info("http请求结果异常：{} {}", response.getStatusLine(), ex.getMessage());
                    throw new HttpUtils.HttpException(request, response, null);
                }
            });
        } catch (IOException e) {
            throw new ServerErrorException(e);
        }
    }

	/**
	 * 发送http post请求
	 * @param url
	 * @param params
	 * @param heads
	 * @return
	 */
	public static String sendHttpPostRequest(String url,Map<String,Object> params,Map<String,String> heads){
		if (StringUtils.isEmpty(url)){
			return null;
		}
		String rtn = "";
		CloseableHttpClient client = HttpClients.createDefault();
		HttpPost httpP = new HttpPost(url);
		ArrayList formparams = new ArrayList();
		if(params != null && params.size() > 0) {
			Set uefEntity = params.keySet();
			Iterator e = uefEntity.iterator();
			while(e.hasNext()) {
				String entity = (String)e.next();
				formparams.add(new BasicNameValuePair(entity, (String)params.get(entity)));
			}
		}
		try {
			UrlEncodedFormEntity uefEntity1 = new UrlEncodedFormEntity(formparams, "UTF-8");
			if(heads != null) {
				Set e1 = heads.keySet();
				Iterator entity1 = e1.iterator();

				while(entity1.hasNext()) {
					String key = (String)entity1.next();
					httpP.setHeader(key, (String)heads.get(key));
				}
			}

			httpP.setEntity(uefEntity1);
			HttpResponse response  = client.execute(httpP);
//          if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
			rtn = EntityUtils.toString(response.getEntity(), "utf-8");
//            }
		} catch (Exception var11) {
			var11.printStackTrace();
			logger.error(var11.getMessage());
		}
		return rtn;
	}
	/*public static void main(String[] args) {
		//商家发货预报
		String shipmentsUrl = "http://lab.yyox.com:83/createInventory";
		//
		Map<String,Object> map = new HashMap<>();
		HttpUtil.sendHttpPostRequest(url,)
	}*/


	/**
	 * POST 上传文件
	 *
	 * @param url
	 * @param
	 * @param headers
	 * @return
	 */
	public static String postFile(String url, Map<String, String> headers, Map<String, String> form) {
		try {
			HttpPost request = new HttpPost(url);

			//设置请求头
			if (!CollectionUtils.isEmpty(headers)) {
				headers.entrySet().forEach(entry -> {
					request.setHeader(entry.getKey(), entry.getValue());
				});
			}

			MultipartEntityBuilder builder = MultipartEntityBuilder.create();
			//添加form表单
			if (null != form && form.keySet().size() > 0) {
				for (String key : form.keySet()) {
					builder.addTextBody(key, form.get(key), ContentType.create("text/plain", Consts.UTF_8));
				}
			}
			//添加文件

			//设置请求体
			request.setEntity(builder.build());

			return DEFAULT_HTTP_CLIENT.execute(request, response -> {
				//HTTP响应信息默认处理方法
				try {
					String responseBody = StreamUtils.copyToString(response.getEntity().getContent(), StandardCharsets.UTF_8);
					if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
						logger.info("http请求结果异常：{} {}", response.getStatusLine(), responseBody);
						throw new HttpUtils.HttpException(request, response, responseBody);
					}
					return responseBody;
				} catch (IOException ex) {
					logger.info("http请求结果异常：{} {}", response.getStatusLine(), ex.getMessage());
					throw new HttpUtils.HttpException(request, response, null);
				}
			});
		} catch (IOException e) {
			throw new ServerErrorException(e);
		}
	}

	/**
     * 处理 请求协议逻辑
     *
     * @param protocol
     * @param targetUrl
     * @return
     */
    public static String resetProtocol(String protocol, String targetUrl) {
        Assert.hasText(protocol);
        Assert.hasText(targetUrl);

        try {
            URL target = new URL(targetUrl);
            if (protocol.equals(target.getProtocol())) {
                return target.toString();
            } else {
                return new URL(protocol, target.getHost(), target.getFile()).toString();
            }
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }
    }

	/**
	 * 下载文件
	 *
	 * @param url
	 * @param filePath
	 */
	public static File downloadFile(String url, String filePath) {
		CloseableHttpClient httpclient = HttpClients.createDefault();
		File file = new File(filePath);
		try {
			HttpGet httpGet = new HttpGet(url);
			CloseableHttpResponse response1 = httpclient.execute(httpGet);
			try {
				System.out.println(response1.getStatusLine());
				HttpEntity httpEntity = response1.getEntity();
				InputStream is = httpEntity.getContent();
				// 根据InputStream 下载文件
				ByteArrayOutputStream output = new ByteArrayOutputStream();
				byte[] buffer = new byte[4096];
				int r = 0;
				while ((r = is.read(buffer)) > 0) {
					output.write(buffer, 0, r);
				}
				FileOutputStream fos = new FileOutputStream(filePath);
				output.writeTo(fos);
				output.flush();
				output.close();
				fos.close();
				EntityUtils.consume(httpEntity);
			} finally {
				response1.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				httpclient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return file;
	}
	/**
	 * post请求
	 * @param url
	 * @param json
	 * @return
	 */
	public static JSONObject doPost(String url, JSONObject json){

		CloseableHttpClient httpclient = HttpClientBuilder.create().build();
		HttpPost post = new HttpPost(url);
		JSONObject response = null;
		try {
			StringEntity s = new StringEntity(json.toString(), Charset.forName("UTF-8"));
			s.setContentEncoding("UTF-8");
			s.setContentType("application/json;charset=utf-8");//发送json数据需要设置contentType
			post.addHeader("Content-type","application/json; charset=utf-8");
			post.setHeader("Accept", "application/json");
			post.setEntity(s);
			HttpResponse res = httpclient.execute(post);
			if(res.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
				String result = EntityUtils.toString(res.getEntity());// 返回json格式：
				logger.info("返回结果{}",result);
				response = JSON.parseObject(result);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return response;
	}

	/**
	 * 发送post请求
	 * @param reqStr 请求参数
	 * @param url 请求地址
	 * @return
	 */
	public static String doRequestPostString(String reqStr, String url) {
		PrintWriter out = null;
		BufferedReader in = null;
		String result = "";
		try {
			URL realUrl = new URL(url);
			// 打开和URL之间的连接
			URLConnection conn = realUrl.openConnection();
			// 设置通用的请求属性
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("Content-type", "application/json;charset=utf-8");
			// 发送POST请求必须设置如下两行
			conn.setDoOutput(true);
			conn.setDoInput(true);
			// 获取URLConnection对象对应的输出流
			out = new PrintWriter(conn.getOutputStream());
			// 发送请求参数
			out.print(reqStr);
			// flush输出流的缓冲
			out.flush();
			// 定义BufferedReader输入流来读取URL的响应
			in = new BufferedReader(
					new InputStreamReader(conn.getInputStream()));
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
		} catch (Exception e) {
			logger.error("发送请求时异常", e);
		}
		//使用finally块来关闭输出流、输入流
		finally{
			try{
				if(out!=null){
					out.close();
				}
				if(in!=null){
					in.close();
				}
			}catch(IOException ex){
				logger.error("关闭流异常", ex);
			}
		}
		return result;
	}

}
